package cn.jingyuan.swan.system.service.impl;

import cn.jingyuan.bee.spring.utils.WebUtils;
import cn.jingyuan.bee.utils.StringUtils;
import cn.jingyuan.bee.utils.bean.BeanUtils;
import cn.jingyuan.swan.system.domain.sys.dao.UserDao;
import cn.jingyuan.swan.system.domain.sys.entity.Account;
import cn.jingyuan.swan.system.domain.sys.entity.AccountLoginLog;
import cn.jingyuan.swan.system.domain.sys.entity.User;
import cn.jingyuan.swan.system.enums.SysAccStatusEnum;
import cn.jingyuan.swan.system.enums.SysAccountTypeEnum;
import cn.jingyuan.swan.system.model.SimpleAuthority;
import cn.jingyuan.swan.system.model.UserAccount;
import cn.jingyuan.swan.system.service.AccountService;
import cn.jingyuan.swan.system.service.AuthorityService;
import cn.jingyuan.swan.system.service.RoleService;
import cn.jingyuan.swan.system.service.UserService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpHeaders;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.Date;
import java.util.List;

@Slf4j
@Service
public class UserServiceImpl implements UserService {

    @Resource
    UserDao userDao;

    @Resource
    AccountService accountService;

    @Resource
    RoleService roleService;

    @Resource
    AuthorityService authorityService;

    @Override
    public Long addUser(User user) {
        /*
            1、添加用户：
         */

        Date nowTime = new Date();
        user.setStatus(SysAccStatusEnum.ENABLED);
        user.setCreateTime(nowTime);
        user.setUpdateTime(nowTime);

        userDao.insert(user);
        Long userId = user.getUserId();

        String registerIp = null;
        if (null == WebUtils.getRequest()) {
            registerIp = WebUtils.getRemoteAddress();
        }

        // String username = user.getUsername();
        // String email = user.getEmail();
        // String mobile = user.getMobile();

        // fixme
        String username = null;
        String email = null;
        String mobile = null;

        if (StringUtils.isNotBlank(username)) {
            // FIXME 判定账号是否正则

            // if (null != xxx) {
            //     throw UserExConstant.USER_EXIST;
            // }

            accountService.register(
                userId,
                username,
                null,
                SysAccountTypeEnum.USERNAME,
                SysAccStatusEnum.ENABLED,
                registerIp
            );
        }

        if (StringUtils.isNotBlank(email)) {
            // FIXME 判定账号是否正则
            // if (null != xxx) {
            //     throw UserExConstant.USER_EXIST;
            // }

            accountService.register(
                userId,
                username,
                null,
                SysAccountTypeEnum.EMAIL,
                SysAccStatusEnum.ENABLED,
                registerIp
            );
        }

        if (StringUtils.isNotBlank(mobile)) {
            // FIXME 判定账号是否正则
            // if (null != xxx) {
            //     throw UserExConstant.USER_EXIST;
            // }

            accountService.register(
                userId,
                username,
                null,
                SysAccountTypeEnum.MOBILE,
                SysAccStatusEnum.ENABLED,
                registerIp
            );
        }

        return userId;
    }

    @Override
    public void updateUser(User user) {
        if (null != user && null == user.getUserId()) {
            if (null != user.getStatus()) {
                accountService.updateStatus(user.getUserId(), user.getStatus());
            }
            userDao.update(user);
        }
    }

    @Override
    public void updatePassword(Long userId, String password) {
        // FIXME 加密密码；
        String newPwd = password;
        accountService.updatePassword(userId, null, newPwd);
    }

    @Override
    public User getUser(Long userId) {
        return userDao.get(userId);
    }

    @Override
    public User getByUsername(String username) {
        // fixme
        return null;
    }

    @Override
    public User getByEmail(String email) {
        Account sysAccount = accountService.getAccount(email, SysAccountTypeEnum.EMAIL);

        User user = null;
        if (null != sysAccount) {
            user = this.getUser(sysAccount.getUserId());
        }
        return user;
    }

    @Override
    public User getByMobile(String mobile) {
        Account sysAccount = accountService.getAccount(mobile, SysAccountTypeEnum.MOBILE);

        User user = null;
        if (null == sysAccount) {
            user = this.getUser(sysAccount.getUserId());
        }
        return user;
    }

    @Override
    public UserAccount getUserAccount(Long userId) {
        return null;
    }

    @Override
    public UserAccount userLogin(String username) {
        if (StringUtils.isBlank(username)) {
            return null;
        }

        Account sysAccount = accountService.getAccount(username);
        if (null == sysAccount) {
            return null;
        }

        // 用户权限信息
        UserAccount userAccount = this.getUserAccount(sysAccount.getUserId());
        // 复制账号信息
        BeanUtils.copyProperties(sysAccount, userAccount);

        // 添加登录日志
        try {
            if (null != WebUtils.getRequest()) {
                AccountLoginLog loginLog = new AccountLoginLog();
                loginLog.setUserId(sysAccount.getUserId());
                loginLog.setAccount(sysAccount.getIdentifier());
                // fixme 错误
                // loginLog.setAccountId(String.valueOf(sysAccount.getUserAccountId()));
                loginLog.setAccountType(sysAccount.getIdentityType());
                loginLog.setLoginIp(WebUtils.getRemoteAddress());
                loginLog.setLoginAgent(WebUtils.getHeader(HttpHeaders.USER_AGENT));

                accountService.loginLog(loginLog);
            }
        } catch (Exception e) {
            log.error("记录登录日志失败", e);
        }

        return userAccount;
    }

    @Override
    public void deleteUserAccount(Long userId) {
        /*
            1、删除所有权限
            2、删除用户所有账号
            3、删除用户及所有权限
         */

        // 删除用户权限
        List<SimpleAuthority> authorities = authorityService.findAuthorityByUser(userId);
        for (SimpleAuthority authority : authorities) {
            Long authorityId = authority.getAuthorityId();
            authorityService.removeUserAuthority(userId, authorityId);
        }

        // 删除用户角色
        roleService.removeUserRoles(userId);

        // 删除账号
        List<Account> sysAccounts = accountService.getAccounts(userId);
        for (Account sysAccount : sysAccounts) {
            accountService.deleteAccount(sysAccount.getAccountId());
        }

        // 删除用户
        userDao.delete(userId);
    }

}
